package com.demo.system.init.sentinel.rule.init;

import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.zookeeper.ZookeeperDataSource;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * @author ：qilong sun
 * @date ：Created in 2020/7/21 15:49
 * @description：
 * @modified By：
 * @version: V1.0$
 */
@Component
@Slf4j
public class ZookeeperSentinelConfig {
    @Value("${server.port}")
    private Integer serverPort;
    @Value("${spring.application.name}")
    private String appName;
    @Value("${sentinel.zookeeper.address}")
    private String sentinelZookeeperAddress;

    /**
     * 规则保存路径
     */
    @Value("${sentinel.rules.flow.path}")
    private String sentinelRulesFlowPath;
    @Value("${sentinel.rules.degrade.path}")
    private String sentinelRulesDegradeFlowPath;
    @Value("${sentinel.rules.paramFlow.path}")
    private String sentinelRulesParamFlowPath;
    @Value("${sentinel.rules.system.path}")
    private String sentinelRulesSystemPath;
    @Value("${sentinel.rules.authority.path}")
    private String sentinelRulesAuthorityPath;
    @Value("${sentinel.rules.cluster.clusterAppAssignMap.path}")
    private String sentinelRulesClusterAppAssignMapPath;

    /**
     * 因为flow和paramFlow在ZookeeperDemoClusterInitFunc文件的init方法读取注册的，所以此处不再注册；
     * 解决持久化单机流控( 即控制台下的FlowControllerV1 逻辑) ，规则单独存储到一个文件，和集群流控规则分开存储。
     * 添加单机流控规则读取
     */
    @PostConstruct
    public void loadRules() {
        // degrade
        ReadableDataSource<String, List<DegradeRule>> degradeRuleDataSource = new ZookeeperDataSource<>(sentinelZookeeperAddress, String.format(sentinelRulesDegradeFlowPath, appName),
                source -> JSON.parseObject(source, new TypeReference<List<DegradeRule>>() {
                })
        );
        DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty());
        // system
        ReadableDataSource<String, List<SystemRule>> systemRuleDataSource = new ZookeeperDataSource<>(sentinelZookeeperAddress, String.format(sentinelRulesSystemPath, appName),
                source -> JSON.parseObject(source, new TypeReference<List<SystemRule>>() {
                })
        );
        SystemRuleManager.register2Property(systemRuleDataSource.getProperty());
        // authority
        ReadableDataSource<String, List<AuthorityRule>> authorityRuleDataSource = new ZookeeperDataSource<>(sentinelZookeeperAddress, String.format(sentinelRulesAuthorityPath, appName),
                source -> JSON.parseObject(source, new TypeReference<List<AuthorityRule>>() {
                })
        );
        AuthorityRuleManager.register2Property(authorityRuleDataSource.getProperty());
    }
}